import { NO_INTERCEPT } from './types'


interface FetchOptions extends RequestInit {
  timeout?: number
  retries?: number
  retryDelay?: number
  [NO_INTERCEPT]?: boolean // 使用Symbol，不会影响实际请求
}

const wait = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms))

/**
 * 封装的fetch函数，支持重试和超时
 * @param url 请求URL
 * @param options 请求选项，包含超时和重试配置
 * @returns Promise<Response>
 */
export const $fetch = async <T = any>(url: string, options: FetchOptions = {}): Promise<T> => {
  const {
    timeout = 0,
    retries = 0,
    retryDelay = 1000,
    [NO_INTERCEPT]: noIntercept = true, // 默认不拦截
    ...fetchOptions
  } = options

  let lastError: Error | null = null

  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      // 创建超时控制器
      const controller = timeout > 0 ? new AbortController() : null
      const timeoutId = controller ? setTimeout(() => controller.abort(), timeout) : null

      // 合并signal
      const signal = controller?.signal || fetchOptions.signal

      try {
        // 使用类型断言
        const finalFetchOptions: RequestInit & { [NO_INTERCEPT]?: boolean } = {
          ...fetchOptions,
          signal,
          [NO_INTERCEPT]: true
        }

        const response = await unsafeWindow.fetch(url, finalFetchOptions)

        // 清除超时定时器
        if (timeoutId) clearTimeout(timeoutId)

        // 检查HTTP状态码，非2xx也认为是错误
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }

        return await response.json()

      } catch (error) {
        // 清除超时定时器
        if (timeoutId) clearTimeout(timeoutId)
        throw error
      }

    } catch (error) {
      lastError = error as Error

      // 如果是最后一次尝试，直接抛出错误
      if (attempt === retries) {
        break
      }

      // 等待一段时间后重试
      if (retryDelay > 0) {
        await wait(retryDelay)
      }
    }
  }

  throw lastError || new Error('Request failed')
}

// 使用示例：
/*
// 基本使用（不超时，不重试）
const response = await $fetch('https://api.example.com/data');
const data = await response.json();

// 设置超时时间（5秒超时）
const response = await $fetch('https://api.example.com/data', {
  timeout: 5000
});

// 设置重试次数（重试3次）
const response = await $fetch('https://api.example.com/data', {
  retries: 3
});

// 完整配置（5秒超时，重试3次，每次重试延迟2秒）
const response = await $fetch('https://api.example.com/data', {
  timeout: 5000,
  retries: 3,
  retryDelay: 2000,
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
});

// 处理错误
try {
  const response = await $fetch('https://api.example.com/data', {
    timeout: 5000,
    retries: 2
  });
  const data = await response.json();
  console.log(data);
} catch (error) {
  if (error.name === 'AbortError') {
    console.error('请求超时');
  } else {
    console.error('请求失败:', error.message);
  }
}
*/